<?php defined('SYSPATH') or die('No direct script access.');

class Library_SoX
{
    /**
    * Обрезать аудиофайл
    *   
    * @param mixed $old_file
    * @param mixed $new_file
    * @param mixed $start
    * @param mixed $duration
    */
    public static function trim($old_file, $new_file, $start, $duration = null)
    {
        self::_check_input_file($old_file);
        self::_remove_output_file($new_file);
        
        $command = $old_file.' '.$new_file.' trim '.self::_number_format($start);
        if ($duration) {
            $command .= ' '.self::_number_format($duration);    
        }
        
        self::_exec_command($command);
        
        self::_check_output_file($new_file);    
    }
    
    /**
    * Зименить громкость звука
    * 
    * @param mixed $old_file
    * @param mixed $new_file
    * @param mixed $volume  (если меньше 1 - тише, больше - громче)
    */
    public static function volume($old_file, $new_file, $volume)
    {
        self::_check_input_file($old_file);
        self::_remove_output_file($new_file);
        
        self::_exec_command('-v '.self::_number_format($volume).' '.$old_file.' '.$new_file);
        
        self::_check_output_file($new_file);    
    }
    
    /**
    * Преобразовать файл в стерео файл с заданным кол-вом каналов
    * 
    * @param mixed $old_file
    * @param mixed $new_file
    * @param mixed $channels
    */
    public static function to_stereo($old_file, $new_file, $channels = 2)
    {
        self::_check_input_file($old_file);
        self::_remove_output_file($new_file);
        
        self::_exec_command($old_file.' -c '.$channels.' '.$new_file);
        
        self::_check_output_file($new_file);    
    }
    
    /**
    * Компрессия
    * 
    * @param mixed $old_file
    * @param mixed $new_file
    * @param mixed $params
    */
    public static function compand($old_file, $new_file, $params)
    {
        // TODO переделать прием параметров по одиночке, а не строкой
        self::_check_input_file($old_file);
        self::_remove_output_file($new_file);
        
        self::_exec_command($old_file.' '.$new_file.' compand '.$params);
        
        self::_check_output_file($new_file);    
    }
    
    /**
    * Затухание
    * 
    * @param mixed $old_file
    * @param mixed $new_file
    * @param mixed $fade_in
    * @param mixed $fade_out
    */
    public static function fade($old_file, $new_file, $fade_in_length = null, $stop_time = null, $fade_out_length = null, $type = 't')
    {
        self::_check_input_file($old_file);
        self::_remove_output_file($new_file);
        
        $fade_in = 0;
        if ($fade_in_length) {
            $fade_in = $fade_in_length;    
        }
        
        $stop = 0;
        if ($stop_time) {
            $stop = $stop_time;    
        }
        
        $fade_out = 0;
        if ($fade_out_length) {
            $fade_out = $fade_out_length;    
        }
        
        self::_exec_command($old_file.' '.$new_file.' fade '.$type.' '.self::_number_format($fade_in).' '.self::_number_format($stop).' '.self::_number_format($fade_out));
        
        self::_check_output_file($new_file);    
    }
    
    /**
    * Наложение файлов друг на друга
    * 
    */
    public static function merge()
    {
        $files = func_get_args();
        $count = count($files);
        
        for ($i = 0; $i < $count-2; $i++) {
            //self::_check_input_file($files[$i]);    
        }
        self::_remove_output_file($files[$count-1]);
        
        self::_exec_command('-m '.implode(' ', $files));
        
        self::_check_output_file($files[$count-1]);    
    }
    
    /**
    * Объединение файлов друг а другом
    * 
    */
    public static function append()
    {
        $files = func_get_args();
        $count = count($files);
        
        for ($i = 0; $i < $count-2; $i++) {
            self::_check_input_file($files[$i]);    
        }
        self::_remove_output_file($files[$count-1]);
        
        self::_exec_command(implode(' ', $files));
        
        self::_check_output_file($files[$count-1]);    
    }
    
    protected static function _check_input_file($file)
    {
        if (!file_exists($file)) {
            throw new Model_Exception('Файла '.$file.' не существует');    
        }
    }
    
    protected static function _remove_output_file($file)
    {
        if (file_exists($file)) {
            unlink($file);
        }
    }
    
    protected static function _check_output_file($file)
    {
        self::_check_input_file($file);
    }
    
    protected static function _number_format($number)
    {
        return number_format($number, 4, '.', '');
    }
    
    protected static function _exec_command($command)
    {
        exec('sox '.$command);
    }
}
